﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using HA.Data;

using HATerrain;
using HA.ModFlow.Infrastructure;

using HA.ModFlow.Domain;

using HA.MT3DMS.DomainLayer;

using HAMath;
using Microsoft.Win32;
using System.IO;
using System.Windows;

using HA.ModFlow.Controls.Windows.MapData;


namespace HA.ModFlow.Application
{
   public class DataOperationModule
    {
       protected DataOperationModule()
       {
 
       }


       static DataOperationModule defaultModule;

       public static DataOperationModule DefaultModule
       {

           get {

               if (defaultModule==null)
               {
                   defaultModule = new DataOperationModule();
                   
               }

               return DataOperationModule.defaultModule; 
           }

       }

       public static Window mainWindow;

        #region 公共函数


       /// <summary>
       /// 数据导入
       /// </summary>
       /// <returns></returns>
       public bool ImportFile(ImportFileType type)
       {
           OpenFileDialog ofd;
           TerrainData td;

           switch (type)
           {
               case ImportFileType.BITMAP:

                   #region 操作

                   CBackImageWpf.winBackImage win = new CBackImageWpf.winBackImage();
                   win.WindowStartupLocation = WindowStartupLocation.CenterScreen;
                   win.Owner = DataCommands.mainWindow;

                   if (win.ShowDialog()==true)
                   {
                       Dictionary<string, BitImageInfoes> bitImagesInfoes = new Dictionary<string, BitImageInfoes>();

                       CImPortImage.InsertImage insertImage;
                       for (int i = 0; i < win.Images.Count; i++)
                       {
                           insertImage = win.Images[i];
                           string filePath = ProjectService.DefaultService.GetProjPath(ProjPath.RESOURCE);
                           string ext = System.IO.Path.GetExtension(insertImage.FileName);
                           string imageDesc = System.IO.Path.GetFileName(insertImage.FileNameNoExen);

                           //获取Id作为文件名
                           string id = ProjectService.DefaultService.Project.AssistData.GetNextBitImageId();
                           string fileNameWithExt = id + ext;
                           filePath += fileNameWithExt;

                           System.IO.File.Copy(insertImage.FileName, filePath, true);

                           //添加导入图片的相关信息
                           BitImageInfoes bitImageInfoes = new BitImageInfoes(id, imageDesc, new System.Drawing.PointF(insertImage.LeftBottomPoint.X,
                               insertImage.LeftBottomPoint.Y),
                               new System.Drawing.PointF(insertImage.RightTopPoint.X,
                                  insertImage.RightTopPoint.Y), insertImage.ImageRect.Width, insertImage.ImageRect.Height);


                           bitImagesInfoes.Add(fileNameWithExt, bitImageInfoes);
                       }

                       ProjectService.DefaultService.Project.AssistData.AddBitImage(bitImagesInfoes);

                       
                   }
                   

                   //CBackImage.frmImportBackImage frmBitmap = new CBackImage.frmImportBackImage();                 
                   //if (frmBitmap.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                   //{
                   //    Dictionary<string, BitImageInfoes> bitImagesInfoes = new Dictionary<string, BitImageInfoes>();

                   //    CImPortImage.InsertImage insertImage;
                   //    for (int i = 0; i < frmBitmap.InsetImageCollection.Count; i++)
                   //    {
                   //        insertImage = frmBitmap.InsetImageCollection[i];
                   //        string filePath = ProjectSerivce.DefaultService.GetProjPath(ProjPath.RESOURCE);
                   //        string ext = System.IO.Path.GetExtension(insertImage.FileName);
                   //        string imageDesc = System.IO.Path.GetFileName(insertImage.FileNameNoExen);

                   //        //获取Id作为文件名
                   //        string id = ProjectSerivce.DefaultService.Project.AssistData.GetNextBitImageId();
                   //        string fileNameWithExt = id + ext;
                   //        filePath += fileNameWithExt;

                   //        System.IO.File.Copy(insertImage.FileName, filePath, true);

                   //        //添加导入图片的相关信息
                   //        BitImageInfoes bitImageInfoes = new BitImageInfoes(id, imageDesc, new System.Drawing.PointF(insertImage.LeftBottomPoint.X,
                   //            insertImage.LeftBottomPoint.Y),
                   //            new System.Drawing.PointF(insertImage.RightTopPoint.X,
                   //               insertImage.RightTopPoint.Y), insertImage.ImageRect.Width, insertImage.ImageRect.Height);


                   //        bitImagesInfoes.Add(fileNameWithExt, bitImageInfoes);
                   //    }

                   //    ProjectSerivce.DefaultService.Project.AssistData.AddBitImage(bitImagesInfoes);
                   //}

                   
                   #endregion

                   break;
               case ImportFileType.DEM:

                   #region 操作
                   
                   ofd = new OpenFileDialog();
                   ofd.Filter = "DEM文件|*.dem";


                   if (ofd.ShowDialog().Value)
                   {
                       try
                       {
                           td = TerrainFileHelper.Open(ofd.FileName);

                           if (td != null)
                           {
                               HA.ModFlow.Controls.Windows.DataOperation.winDemImporter winDem = new Controls.Windows.DataOperation.winDemImporter(ProjectService.DefaultService.Project, td, System.IO.Path.GetFileNameWithoutExtension(ofd.FileName));

                               winDem.WindowStartupLocation = WindowStartupLocation.CenterScreen;
                               winDem.ShowDialog();
                           }
                       }
                       catch
                       {
                           return false;
                       }
                   }
                   
                   #endregion

                   break;
               case ImportFileType.CAD:
                   break;
               case ImportFileType.TXTCSV:

                   #region 操作
                   
                   HA.ModFlow.Controls.Windows.winImportTxtCsvFile winImport = new Controls.Windows.winImportTxtCsvFile(ProjectService.DefaultService.Project);
                   winImport.Owner = mainWindow;
                   if (winImport.ShowDialog() == true)
                   {
                       switch (winImport.ImportDataType)
                       {
                           case ImportWizardType.SCATTER2D:

                               if (winImport.IsDataValid && winImport.Scatter2D != null)
                                   ProjectService.DefaultService.Project.Scatter2dData.Add(winImport.Scatter2D);

                               break;
                           case ImportWizardType.SCATTER3D:


                               break;
                           default:
                               break;
                       }

                   }
                   
                   #endregion

                   break;
               case ImportFileType.SHAPE:
                   break;
               default:
                   break;
           }



           return true;
       }



       /// <summary>
       /// 数据插值
       /// </summary>
       public void InterpolationData()
       {
 
       }


       public void ReadModflowResult()
       {

           string path = ProjectService.DefaultService.GetProjPath(ProjPath.SOLUTION);

           if (ProjectService .DefaultService .Project.CurentFlowVectorData !=null )
           {
               ProjectService.DefaultService.Project.CurentFlowVectorData = null;
           }


           ProjectService.DefaultService.Project.MfData.ReadOutputResult(path);


           if (ProjectService.DefaultService.Project.MfData==null )
           {
               return;
           }


           DSModflow dsModflow = new DSModflow();
           dsModflow.Name = "MODFLOW结果";


           List<CellCenterDataSet3d> heads = ProjectService.DefaultService.Project.MfData.MfResult.CellCenterIHeadDataSet3d;
           DSGrid3d grid3d = new DSGrid3d("Head",heads);
           grid3d.Name = "水头";

           dsModflow.Collecion.Add(grid3d);


           List<CellCenterDataSet3d> dropDown = ProjectService.DefaultService.Project.MfData.MfResult.CellCenterDropDownData;
           DSGrid3d dropDownGrid3d = new DSGrid3d("DropDown", dropDown);
           dropDownGrid3d.Name = "降深";

           dsModflow.Collecion.Add(dropDownGrid3d);




           //grid3d

           dsModflow.CcfData = ProjectService.DefaultService.Project.MfData.MfResult.CcfDataSet;

           //逝去时间
           dsModflow.MfTimeStepLabel = ProjectService.DefaultService.Project.MfData.MfResult.MfTimeStepLabel;
           //各个应力期的IBound
           dsModflow.TimeStepIBound = ProjectService.DefaultService.Project.MfData.MfResult.GetStressStepIBound ();


           ProjectService.DefaultService.Project.Grid3dData.MainGrid.Add(dsModflow);

           //ProjectSerivce.DefaultService.Project.CurrentDSGrid = grid3d;

           UIModule.DefaultModule.ProjectViewModel.SetFirstDSSelected(dsModflow);



           ///重置当前项目中的显示条件
           ///
           //UIModule.DefaultModule.ProjectViewModel.TsvViewModel.DsGrid = grid3d;

           //ProjectSerivce.DefaultService.Project.CurrentDSData = grid3d.GetDataSet(0);



       }


       public void ReadMT3DResult()
       {

           string path = ProjectService.DefaultService.GetProjPath(ProjPath.SOLUTION);

           ProjectService.DefaultService.Project.Mt3dmsData.ReadOutputResult(path);


           DSGrid3dCollecion dsMt = new DSGrid3dCollecion("MT3DMSResult");
           dsMt.Name = "MT3DMS结果";



           MT3DMSData data = ProjectService.DefaultService.Project.Mt3dmsData;

           if ( ProjectService.DefaultService.Project.Mt3dmsData.Mt3dOutputFileResult ==null )
           {
               return;
           }


           foreach (MT3DSpeciesResult item in data.Mt3dOutputFileResult.AllSpeciesMT3DResultList)
	        {



                List<CellCenterDataSet3d> dataset = new List<CellCenterDataSet3d>();

              
                 

                foreach (OutputFileData fileData in item.SpeciesOutputFileResult)
                {

                    dataset.Add(fileData.CellCenterGridValue);
                    

                }


                DSGrid3d grid3d = new DSGrid3d(item.SpecieName, dataset);

                dsMt.Collecion.Add(grid3d);
		 
	        }





           ProjectService.DefaultService.Project.Grid3dData.MainGrid.Add(dsMt);


           ///重置当前项目中的显示条件
           ///


            UIModule.DefaultModule.ProjectViewModel.SetFirstDSSelected(dsMt);



           //DSGrid3d grid = dsMt.GetDSGrid(0);


           //UIModule.DefaultModule.ProjectViewModel.TsvViewModel.DsGrid = grid;

           //if (grid!=null)
           //{

           //    UIModule.DefaultModule.ProjectViewModel.TsvViewModel.DsGrid = grid3d;

           //    ProjectSerivce.DefaultService.Project.CurrentDSData = grid.GetDataSet(0);

               
           //}


         


          

 
       }


       /// <summary>
       /// 二维离散点差值到网格图层   反距离平方法
       /// </summary>
       /// <param name="scatter"></param>
       /// <param name="project"></param>
       public void Scatter2DToModlfowLayer(Scatter2D scatter,Project project)
       {
           HA.ModFlow.Controls.Windows.DataOperation.winInterpolateToModflow win = new Controls.Windows.DataOperation.winInterpolateToModflow(scatter, project);
           win.Owner = mainWindow;
           win.ResizeMode = ResizeMode.NoResize;
           win.WindowStartupLocation = WindowStartupLocation.CenterScreen;
           if ( win.ShowDialog()==true)
           {

               List<ScatterToModflowLayer> maps = win.Maps;



               bool bHaveElevation=false;
               bool bStartingHead = false;

               foreach (ScatterToModflowLayer item in maps)
               {

                   DSScatter ds = scatter.GetDataSet(item.ScatterName);
                   if (ds.Points.Count <= 0)
                   {
                       continue;
                   }

                   Point2D[,] pts;

                   switch (item.Layer.LayerType)
                   {
                       case ModflowLayerType.TOPELEVATION:

                          pts=  project.MfData.GridData.GetElevationCoords2D();

                          bHaveElevation = true;
                           break;
                       case ModflowLayerType.BOTELEVATION:

                           pts = project.MfData.GridData.GetElevationCoords2D();


                           bHaveElevation = true;
                           break;
                       case ModflowLayerType.STARTINGHEAD:
                           pts = project.MfData.GridData.GetElevationCoords2D();

                           bStartingHead = true;
                           break;
                       default:

                           pts=null;

                           break;
                   }


                   if (pts==null)
                   {
                       return;
                       
                   }

                   int nrow = project.MfData.GridData.RowsCount;

                   int ncol = project.MfData.GridData.ColsCount;



                   ///用于返回的实际结果
                   double[,] data=new double[nrow,ncol];



                   List<Point2D> pt2d=new List<Point2D> ();

                   for (int i = 0; i < nrow; i++)
                   {
                       for (int j = 0; j < ncol; j++)
                       {

                           pt2d.Add(new Point2D(pts[i,j].X,pts[i,j].Y));

                           
                       }
                       
                   }

                   

                 //double[] result= IDWScatter2D.Interoplation(ds.Points,pt2d,project.InterpolationOption2D);
                   double[] result=null;
                 # region 刘加

                 HA.ModFlow.Controls.Windows.DataOperation.winKrigProgressBar bar = new Controls.Windows.DataOperation.winKrigProgressBar();
                 bar.Min = 0;
                 int counter = pt2d.Count / 100;
                 if (counter == 0) counter = 1;
                 bar.Max = pt2d.Count / counter;  //进度条最大值根据数据动态变化
                 bar.Owner = mainWindow;
                 bar.Show();
                 bar.Value = 1;

                 switch (project.InterpolationOption2D.Interpolatetype)
                 {
                     case InterpolateType.IDW:
                         //反距离平方法，以前的代码
                         //result = IDWScatter2D.Interoplation(dssPoint, pt2d, project.InterpolationOption2D);
                          result = IDWScatter2D.Interoplation(ds.Points, pt2d, project.InterpolationOption2D);
                         break;
                     case InterpolateType.Kriging:
                         //普通克里金法，刘加
                         List<KrigingPoint> Points = new List<KrigingPoint>();
                         foreach (DSSPoint pt in ds.Points)
                         {
                             Points.Add(new KrigingPoint(pt.X, pt.Y, pt.Value));
                         }

                         OridinateKriging krig = new OridinateKriging(Points);
                         krig.Ellipsoid = project.InterpolationOption2D.KrigingOption.Ellipsoid; //搜索半径
                         krig.Model = project.InterpolationOption2D.KrigingOption.ModelVariogram; //模型变差函数
                         krig.SearchOption = project.InterpolationOption2D.KrigingOption.SearchOption;  //搜索选项

                         List<double> resultValues = new List<double>();

                         DateTime time1 = new DateTime();
                         time1 = DateTime.Now;

                         //foreach (Point2D pt in pt2d)
                         //{
                         //    KrigingPoint krigPt = new KrigingPoint(pt.X, pt.Y);
                         //    resultValues.Add(krig.GetValue(krigPt));
                         //    bar.Value = bar.Value + 1;
                         //}


                         KrigingPoint krigPt = new KrigingPoint(0, 0);



                         for (int i = 0; i < pt2d.Count; i++)
                         {
                             krigPt.X = pt2d[i].X;
                             krigPt.Y = pt2d[i].Y;
                             resultValues.Add(krig.GetValue(krigPt));
                             if (i % counter == 0)
                             {
                                 bar.Value += 1;
                             }
                         }

                         DateTime time2 = new DateTime();
                         time2 = DateTime.Now;

                         result = resultValues.ToArray();
                         break;
                 }


                 bar.Close();

                 # endregion

                   ///结果赋值

                 for (int i = 0; i < nrow; i++)
                 {
                     for (int j = 0; j < ncol; j++)
                     {

                        data[i,j]=result[i*ncol+j];


                     }

                 }



                   //传回主程

                 switch (item.Layer.LayerType)
                 {
                     case ModflowLayerType.TOPELEVATION:

                        project.MfData.GridData.Elevations[0] = data;

                         break;
                     case ModflowLayerType.BOTELEVATION:

                         project.MfData.GridData.Elevations[item.Layer.LayerIndex+1]=data;

                         break;
                     case ModflowLayerType.STARTINGHEAD:

                         project.MfData.GridData.WaterGrid.Layers[item.Layer.LayerIndex ].InitHead = data;

                         break;
                     default:

                         pts = null;

                         break;
                 }



                   

               }



               ///要求刷新高程
               ///

               if (bHaveElevation)
               {

                   project.MfData.GridData.AskElevationChanged();
                   if (project.CurrentDSData != null)
                   {
                       if (project.CurrentDSData.Label == "顶部高程")
                       {
                           project.CurrentDSData = project.MfData.GridData.GetTopElevationDs();
                       }
                       else if (project.CurrentDSData.Label == "底部高程")
                       {
                           project.CurrentDSData = project.MfData.GridData.GetBotElevationDs();
                       }
                   }
               }

               if (bStartingHead)
               {
                   if (project.CurrentDSData != null && project.CurrentDSData.Label == "初始水头")
                   {
                       project.CurrentDSData = project.MfData.GridData.GetIHeadDs();
                   }
               }


               
           } 

 
       }


       /// <summary>
       /// 二维离散点差值到三维网格   反距离平方法
       /// </summary>
       /// <param name="scatter2D"></param>
       /// <param name="project"></param>
       /// <returns></returns>
       public double[,] Scatter2DToGrid3d(Scatter2D scatter2D, Project project, ref string valueNameLabel)
       {
           if (scatter2D == null || scatter2D.DataSet == null || scatter2D.ValueNames == null || scatter2D.DataSet.Count <= 0 || scatter2D.ValueNames.Count != scatter2D.DataSet[0].Values.Count || project == null || project.Grid3dData == null || project.Grid3dData.MainGrid == null || project.Grid3dData.MainGrid.ModFlowGrid == null)
           {
               return null;
           }

           double[,] valueResult = null;

           Scatter2D sca = scatter2D;
           List<ScatterPoint> scatter = sca.DataSet;




           ///在这里循环所有可用的Coverage,然后弹出窗体以提供用户选择

           int[] indexInList = new int[1];  //存储使用哪个value值  顺序为List<string> _valueNames中的index
           //List<double> valueScatter2D = new List<double>();

           winConceptualFrame win = new winConceptualFrame(sca, ChooseConfigeType.Scatter2DValueChoose, indexInList);
           win.Owner = mainWindow;
           win.ResizeMode = ResizeMode.NoResize;
           win.WindowStartupLocation = WindowStartupLocation.CenterScreen;
           if (win.ShowDialog() == true)
           {
               if (win.DialogResult == true)
               {
                   if (indexInList != null && indexInList[0] >= 0 && indexInList[0] <= scatter.Count - 1)
                   {

                       //取得离散点指定使用的value
                       if (scatter != null)
                       {
                           List<DSSPoint> dssPoint = new List<DSSPoint>();
                           for (int i = 0; i < scatter.Count; i++)
                           {
                               DSSPoint point = new DSSPoint(scatter[i].Id, scatter[i].Values[indexInList[0]], scatter[i].X, scatter[i].Y);
                               dssPoint.Add(point);
                           }
                           if (sca.ValueNames.Count > 0)
                           {
                               //用于CellCenterDataSet3d中构造标签
                               valueNameLabel = sca.ValueNames[indexInList[0]];
                           }


                           int nrow = project.Grid3dData.MainGrid.ModFlowGrid.RowsCount;
                           int ncol = project.Grid3dData.MainGrid.ModFlowGrid.ColsCount;


                           Point2D[,] pts = project.Grid3dData.MainGrid.ModFlowGrid.GetElevationCoords2D();


                           List<Point2D> pt2d = new List<Point2D>();
                           for (int row = 0; row < nrow; row++)
                           {
                               for (int col = 0; col < ncol; col++)
                               {
                                   pt2d.Add(new Point2D(pts[row, col].X, pts[row, col].Y));
                               }
                           }



                           //double[] result = IDWScatter2D.Interoplation(dssPoint, pt2d, project.InterpolationOption2D);

                           double[] result = null; // = IDWScatter2D.Interoplation(dssPoint, pt2d, project.InterpolationOption2D);

                           # region 刘加

                           HA.ModFlow.Controls.Windows.DataOperation.winKrigProgressBar bar = new Controls.Windows.DataOperation.winKrigProgressBar();
                           bar.Min = 0;
                           int counter = pt2d.Count / 100;
                           if (counter == 0) counter = 1;
                           bar.Max = pt2d.Count / counter;  //进度条最大值根据数据动态变化
                           bar.Owner = mainWindow;
                           bar.Show();
                           bar.Value = 1;

                           switch (project.InterpolationOption2D.Interpolatetype)
                           {
                               case InterpolateType.IDW:
                                   //反距离平方法，以前的代码
                                   result = IDWScatter2D.Interoplation(dssPoint, pt2d, project.InterpolationOption2D);
                                   break;
                               case InterpolateType.Kriging:
                                   //普通克里金法，刘加
                                   List<KrigingPoint> Points = new List<KrigingPoint>();
                                   foreach (DSSPoint pt in dssPoint)
                                   {
                                       Points.Add(new KrigingPoint(pt.X, pt.Y, pt.Value));
                                   }

                                   OridinateKriging krig = new OridinateKriging(Points);
                                   krig.Ellipsoid = project.InterpolationOption2D.KrigingOption.Ellipsoid; //搜索半径
                                   krig.Model = project.InterpolationOption2D.KrigingOption.ModelVariogram; //模型变差函数
                                   krig.SearchOption = project.InterpolationOption2D.KrigingOption.SearchOption;  //搜索选项

                                   List<double> resultValues = new List<double>();

                                   DateTime time1 = new DateTime();
                                   time1 = DateTime.Now;

                                   //foreach (Point2D pt in pt2d)
                                   //{
                                   //    KrigingPoint krigPt = new KrigingPoint(pt.X, pt.Y);
                                   //    resultValues.Add(krig.GetValue(krigPt));
                                   //    bar.Value = bar.Value + 1;
                                   //}


                                   KrigingPoint krigPt = new KrigingPoint(0, 0);

                                  

                                   for (int i = 0; i < pt2d.Count; i++)
                                   {
                                       krigPt.X = pt2d[i].X;
                                       krigPt.Y = pt2d[i].Y;
                                       resultValues.Add(krig.GetValue(krigPt));
                                       if (i%counter ==0)
                                       {
                                           bar.Value += 1;
                                       }
                                   }
                                  
                                   DateTime time2 = new DateTime();
                                   time2 = DateTime.Now;

                                   result = resultValues.ToArray();
                                   break;
                           }


                           bar.Close();

                           # endregion



                           ///用于返回的实际结果
                           ///
                           valueResult = new double[nrow, ncol];//平面四边形单元格

                           ///结果赋值

                           for (int i = 0; i < nrow; i++)
                           {
                               for (int j = 0; j < ncol; j++)
                               {

                                   valueResult[i, j] = result[i * ncol + j];

                               }
                           }

                       }

                   }
               }
           }

           return valueResult;

       }





        #endregion

   }
   
}
